home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / hamradio / tnos-2.000 / tnos-2 / lzhuf.c < prev    next >
C/C++ Source or Header  |  1996-06-22  |  36KB  |  1,276 lines

  1. /* This STANDALONE variable doesn't work to build a Standalone LZHUF executable. */
  2. #undef  STANDALONE 1
  3. /*
  4.  ************************************************************
  5.  lzhuf.c
  6.  written by Haruyasu Yoshizaki 11/20/1988
  7.  some minor changes 4/6/1989
  8.  comments translated by Haruhiko Okumura 4/7/1989
  9.  ************************************************************
  10.  */
  11. #include "ctype.h"
  12.  
  13. #ifndef STANDALONE
  14. #include "global.h"
  15. #include <time.h>
  16. #else
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #define LZHUF 1
  21. #define mallocw malloc
  22. #endif
  23.  
  24. #ifndef UNIX
  25. #include <alloc.h>
  26. #endif
  27.  
  28. #if defined(LZHUF) || defined(FBBCMP)
  29. #include "proc.h"
  30. #include "socket.h"
  31. #include "timer.h"
  32. #include "usock.h"
  33. #include "netuser.h"
  34. #include "session.h"
  35.  
  36. #include "lzhuf.h"
  37.  
  38. #undef  DEBUG  1
  39. #undef  DEBUG2 1
  40.  
  41. #if !defined(_lint) && !defined(MSDOS)
  42. static char rcsid[] OPTIONAL = "$Id: lzhuf.c,v 1.10 1996/06/22 18:20:37 root Exp root $";
  43. #endif
  44.  
  45. #if defined(CATALOG) && !defined(STANDALONE)
  46. #include "catalog.h"
  47.  
  48. #define CAT lzhuf_catalog
  49.  
  50. #define ErrorEncode    __STR(0)
  51. #define lostremote    __STR(1)
  52. #define ErrorDecode    __STR(2)
  53. #define Erroropening    __STR(3)
  54. #define ENCODEratio    __STR(4)
  55. #define DECODEratio    __STR(5)
  56.  
  57. #else /* CATALOG */
  58. static const char DFAR ErrorEncode[] = "FWDCMP: Error from Encode() rc = %d";
  59. static const char DFAR lostremote[] = "FBBFWD: Lost the remote connection in recv_yapp()";
  60. static const char DFAR ErrorDecode[] = "FWDCMP: Error from Decode() rc = %d";
  61. static const char DFAR Erroropening[] = "FBBFWD: Error opening %s in %s\n";
  62. static const char DFAR ENCODEratio[] = "FWDCMP: ENCODE:  In: %-8ld  Out: %-8ld (%ld%%)\n";
  63. static const char DFAR DECODEratio[] = "FWDCMP: DECODE:  In: %-8ld  Out: %-8ld (%ld%%)\n";
  64. #endif /* CATALOG */
  65.  
  66.  
  67. static const char DFAR Encodestr[] = "Encode()";
  68. static const char DFAR Decodestr[] = "Decode()";
  69.  
  70. #ifdef STANDALONE
  71. #undef free
  72. #undef malloc
  73. #define tcmdprintf printf
  74. int FBBtrace = 1;
  75. #endif
  76.  
  77. void AllocDataBuffers(struct fwd *f) {
  78.    f->lzhuf           = mallocw(sizeof(struct lzhufstruct));
  79. #if 0
  80.    f->tmpBuffer       = mallocw(260);
  81. #endif
  82.  
  83.    f->lzhuf->data_type = 0;        /* 0 means not allocated yet. */
  84.    f->lzhuf->data     = malloc(sizeof(struct lzhufdata));
  85.    if(f->lzhuf->data != NULLLZHUFDATA)
  86.       f->lzhuf->data_type = 2;        /* 2 means big buffer + lower memory. */
  87.  
  88.    if(f->lzhuf->data_type == 0) {
  89.       f->lzhuf->data_type = 1;        /* 1 means small buffers + lower memory. */
  90.       f->lzhuf->dad       = mallocw((N + 1) * sizeof(int));
  91.       f->lzhuf->lson      = mallocw((N + 1) * sizeof(int));
  92.       f->lzhuf->rson      = mallocw((N + 257) * sizeof(int));
  93.       f->lzhuf->text_buf  = mallocw((N + F - 1) * sizeof(unsigned char));
  94.       f->lzhuf->freq      = mallocw((T + 1) * sizeof(unsigned));
  95.       f->lzhuf->prnt      = mallocw((T + N_CHAR) * sizeof(int));
  96.       f->lzhuf->son       = mallocw((T) * sizeof(int));
  97.    } else {
  98.       /* point pointers to correct spot in large buffer. */
  99.       f->lzhuf->dad       = f->lzhuf->data->dad;
  100.       f->lzhuf->rson      = f->lzhuf->data->rson;
  101.       f->lzhuf->lson      = f->lzhuf->data->lson;
  102.       f->lzhuf->text_buf  = f->lzhuf->data->text_buf;
  103.       f->lzhuf->freq      = f->lzhuf->data->freq;
  104.       f->lzhuf->prnt      = f->lzhuf->data->prnt;
  105.       f->lzhuf->son       = f->lzhuf->data->son;
  106.    }
  107.    f->lzhuf->codesize = 0;
  108.    f->lzhuf->getbuf   = 0;
  109.    f->lzhuf->getlen   = 0;
  110.    f->lzhuf->putbuf   = 0;
  111.    f->lzhuf->putlen   = 0;
  112.    f->lzhuf->code     = 0;
  113.    f->lzhuf->len      = 0;
  114. }
  115.  
  116. void FreeDataBuffers(struct fwd *f) {
  117. #if 0
  118.    free(f->tmpBuffer);
  119. #endif
  120.  
  121.    if(f->lzhuf->data_type == 1) {
  122.       /* Free lower memory blocks. */
  123.       free(f->lzhuf->dad);
  124.       free(f->lzhuf->lson);
  125.       free(f->lzhuf->rson);
  126.       free(f->lzhuf->text_buf);
  127.       free(f->lzhuf->freq);
  128.       free(f->lzhuf->prnt);
  129.       free(f->lzhuf->son);
  130.    } else
  131.    if(f->lzhuf->data_type == 2) {
  132.       /* Free lower memory block. */
  133.       free(f->lzhuf->data);
  134.    }
  135.  
  136.    free(f->lzhuf);
  137.    f->lzhuf = NULLLZHUFSTRUCT;
  138. }
  139.  
  140. int  Encode    (int, char *, char *,struct lzhufstruct *, int trace);
  141. int  Decode    (int, char *, char *, struct lzhufstruct *, int addex, int trace);
  142. int  GetBit    (struct lzhufstruct *);
  143. unsigned short GetByte   (struct lzhufstruct *);
  144. void Putcode   (struct lzhufstruct *, int, unsigned);
  145. void EncodeEnd (struct lzhufstruct *);
  146. int  DecodeChar(struct lzhufstruct *);
  147.  
  148.  
  149. void InitTree  (struct lzhufstruct *);
  150. void InsertNode(struct lzhufstruct *, int);
  151. void StartHuff (struct lzhufstruct *);
  152. void reconst   (struct lzhufstruct *);
  153. void update    (struct lzhufstruct *, int);
  154. void EncodeChar(struct lzhufstruct *, unsigned);
  155. void EncodePosition(struct lzhufstruct *, unsigned);
  156. int  DecodePosition(struct lzhufstruct *);
  157. void DeleteNode(struct lzhufstruct *, int);
  158. int  recvbuf   (int,char *,unsigned);
  159.  
  160. /********** LZSS compression **********/
  161.  
  162. void InitTree(struct lzhufstruct *lzhuf)  /* initialize trees */
  163. {
  164.    int  i;
  165.  
  166.    for (i = N + 1; i <= N + 256; i++)
  167.        lzhuf->rson[i] = NIL;                  /* root */
  168.    for (i = 0; i < N; i++)
  169.        lzhuf->dad[i] = NIL;                   /* node */
  170. }
  171.  
  172. void InsertNode(struct lzhufstruct *lzhuf, int r)  /* insert to tree */
  173. {
  174.    int  i, p, cmp;
  175.    unsigned char  *key;
  176.    unsigned c;
  177.  
  178.    cmp = 1;
  179.    key = &lzhuf->text_buf[r];
  180.    p = N + 1 + key[0];
  181.    lzhuf->rson[r] = lzhuf->lson[r] = NIL;
  182.    lzhuf->match_length = 0;
  183.    for(;;) {
  184.       if(cmp >= 0) {
  185.          if(lzhuf->rson[p] != NIL)
  186.             p = lzhuf->rson[p];
  187.          else {
  188.             lzhuf->rson[p] = r;
  189.             lzhuf->dad[r] = p;
  190.             return;
  191.          }
  192.       } else {
  193.          if(lzhuf->lson[p] != NIL)
  194.             p = lzhuf->lson[p];
  195.          else {
  196.             lzhuf->lson[p] = r;
  197.             lzhuf->dad[r] = p;
  198.             return;
  199.          }
  200.       }
  201.       for(i = 1; i < F; i++)
  202.          if((cmp = key[i] - lzhuf->text_buf[p + i]) != 0)
  203.             break;
  204.       if(i > THRESHOLD) {
  205.          if(i > lzhuf->match_length) {
  206.             lzhuf->match_position = ((r - p) & (N - 1)) - 1;
  207.             if((lzhuf->match_length = i) >= F)
  208.                break;
  209.          }
  210.          if(i == lzhuf->match_length) {
  211.             if((c = ((r - p) & (N - 1)) - 1) < (unsigned)lzhuf->match_position) {
  212.                lzhuf->match_position = c;
  213.             }
  214.          }
  215.       }
  216.    }
  217.    lzhuf->dad[r] = lzhuf->dad[p];
  218.    lzhuf->lson[r] = lzhuf->lson[p];
  219.    lzhuf->rson[r] = lzhuf->rson[p];
  220.    lzhuf->dad[lzhuf->lson[p]] = r;
  221.    lzhuf->dad[lzhuf->rson[p]] = r;
  222.    if(lzhuf->rson[lzhuf->dad[p]] == p)
  223.       lzhuf->rson[lzhuf->dad[p]] = r;
  224.    else
  225.       lzhuf->lson[lzhuf->dad[p]] = r;
  226.    lzhuf->dad[p] = NIL;  /* remove p */
  227. }
  228.  
  229.  
  230. void DeleteNode(struct lzhufstruct *lzhuf, int p)  /* remove from tree */
  231. {
  232.    int  q;
  233.  
  234.    if(lzhuf->dad[p] == NIL)
  235.       return;                 /* not registered */
  236.    if(lzhuf->rson[p] == NIL)
  237.       q = lzhuf->lson[p];
  238.    else
  239.    if(lzhuf->lson[p] == NIL)
  240.       q = lzhuf->rson[p];
  241.    else {
  242.       q = lzhuf->lson[p];
  243.       if(lzhuf->rson[q] != NIL) {
  244.          do {
  245.             q = lzhuf->rson[q];
  246.          } while (lzhuf->rson[q] != NIL);
  247.          lzhuf->rson[lzhuf->dad[q]] = lzhuf->lson[q];
  248.          lzhuf->dad[lzhuf->lson[q]] = lzhuf->dad[q];
  249.          lzhuf->lson[q] = lzhuf->lson[p];
  250.          lzhuf->dad[lzhuf->lson[p]] = q;
  251.       }
  252.       lzhuf->rson[q] = lzhuf->rson[p];
  253.       lzhuf->dad[lzhuf->rson[p]] = q;
  254.    }
  255.    lzhuf->dad[q] = lzhuf->dad[p];
  256.    if(lzhuf->rson[lzhuf->dad[p]] == p)
  257.       lzhuf->rson[lzhuf->dad[p]] = q;
  258.    else
  259.       lzhuf->lson[lzhuf->dad[p]] = q;
  260.    lzhuf->dad[p] = NIL;
  261. }
  262.  
  263. /* Huffman coding */
  264.  
  265. /* table for encoding and decoding the upper 6 bits of position */
  266.  
  267. /* for encoding */
  268. #define MAX_P_LEN 64
  269. uchar p_len[MAX_P_LEN] = {
  270.         0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
  271.         0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06,
  272.         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  273.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  274.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  275.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  276.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  277.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
  278. };
  279.  
  280. uchar p_code[MAX_P_LEN] = {
  281.         0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68,
  282.         0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C,
  283.         0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC,
  284.         0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE,
  285.         0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE,
  286.         0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE,
  287.         0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
  288.         0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
  289. };
  290.  
  291. /* for decoding */
  292. #define MAX_D_LEN 256
  293. uchar d_code[MAX_D_LEN] = {
  294.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  295.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  296.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  297.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  298.         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  299.         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  300.         0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  301.         0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  302.         0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  303.         0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  304.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  305.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  306.         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  307.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  308.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  309.         0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
  310.         0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
  311.         0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
  312.         0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
  313.         0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
  314.         0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
  315.         0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
  316.         0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
  317.         0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
  318.         0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
  319.         0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
  320.         0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
  321.         0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
  322.         0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
  323.         0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
  324.         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  325.         0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
  326. };
  327.  
  328. uchar d_len[MAX_D_LEN] = {
  329.         0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  330.         0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  331.         0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  332.         0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  333.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  334.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  335.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  336.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  337.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  338.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  339.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  340.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  341.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  342.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  343.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  344.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  345.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  346.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  347.         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  348.         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  349.         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  350.         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  351.         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  352.         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  353.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  354.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  355.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  356.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  357.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  358.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  359.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  360.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  361. };
  362.  
  363. int GetBit(struct lzhufstruct *lzhuf)        /* get one bit */
  364. {
  365.    register unsigned i;
  366.    register unsigned dx = lzhuf->getbuf;
  367.    register unsigned char glen = lzhuf->getlen;
  368.    
  369.    while(glen <= 8) {
  370.       i = getc(lzhuf->iFile);
  371.       if ((int)i < 0)
  372.        i = 0;
  373.       dx |= i << (8 - glen);
  374.       glen += 8;
  375.    }
  376.    lzhuf->getbuf = dx << 1;
  377.    lzhuf->getlen = glen - 1;
  378.    return (dx & 0x8000) ? 1 : 0;
  379. }
  380.  
  381.  
  382. unsigned short GetByte(struct lzhufstruct *lzhuf)       /* get one byte */
  383. {
  384.    register unsigned i;
  385.    register unsigned dx = lzhuf->getbuf;
  386.    register unsigned char glen = lzhuf->getlen;
  387.  
  388.    while(glen <= 8) {
  389.       i = getc(lzhuf->iFile);
  390.       if ((int)i < 0)
  391.        i = 0;
  392.       dx |= i << (8 - glen);
  393.       glen += 8;
  394.    }
  395.    lzhuf->getbuf = dx << 8;
  396.    lzhuf->getlen = glen - 8;
  397.    return (dx >> 8) & 0xff;
  398. }
  399.  
  400.  
  401. void Putcode(struct lzhufstruct *lzhuf, int l, unsigned c)         /* output c bits of code */
  402. {
  403.    lzhuf->putbuf |= c >> lzhuf->putlen;
  404.    if((lzhuf->putlen += l) >= 8) {
  405.       if(putc(lzhuf->putbuf >> 8, lzhuf->oFile) == EOF) {
  406.          return;
  407.       }
  408.       if((lzhuf->putlen -= 8) >= 8) {
  409.          if(putc(lzhuf->putbuf, lzhuf->oFile) == EOF) {
  410.             return;
  411.          }
  412.          lzhuf->codesize += 2;
  413.          lzhuf->putlen -= 8;
  414.          lzhuf->putbuf = c << (l - lzhuf->putlen);
  415.       } else {
  416.          lzhuf->putbuf <<= 8;
  417.          lzhuf->codesize++;
  418.       }
  419.    }
  420. }
  421.  
  422.  
  423. /* initialization of tree */
  424.  
  425. void StartHuff(struct lzhufstruct *lzhuf)
  426. {
  427.    int i, j;
  428.  
  429.    for(i = 0; i < N_CHAR; i++) {
  430.        lzhuf->freq[i] = 1;
  431.        lzhuf->son[i] = i + T;
  432.        lzhuf->prnt[i + T] = i;
  433.    }
  434.    i = 0; j = N_CHAR;
  435.    while(j <= R) {
  436.        lzhuf->freq[j] = lzhuf->freq[i] + lzhuf->freq[i + 1];
  437.        lzhuf->son[j] = i;
  438.        lzhuf->prnt[i] = lzhuf->prnt[i + 1] = j;
  439.        i += 2; j++;
  440.    }
  441.    lzhuf->freq[T] = 0xffff;
  442.    lzhuf->prnt[R] = 0;
  443.    lzhuf->putlen = lzhuf->getlen = 0;
  444.    lzhuf->putbuf = lzhuf->getbuf = 0;
  445. }
  446.  
  447.  
  448. /* reconstruction of tree */
  449. void reconst(struct lzhufstruct *lzhuf)
  450. {
  451.    int i, j, k;
  452.    unsigned first;
  453.  
  454.    /* collect leaf nodes in the first half of the table */
  455.    /* and replace the freq by (freq + 1) / 2. */
  456.    j = 0;
  457.    for(i = 0; i < T; i++) {
  458.        if(lzhuf->son[i] >= T) {
  459.           lzhuf->freq[j] = (lzhuf->freq[i] + 1) / 2;
  460.           lzhuf->son[j] = lzhuf->son[i];
  461.           j++;
  462.        }
  463.    }
  464.    /* begin constructing tree by connecting sons */
  465.    for(i = 0, j = N_CHAR; j < T; i += 2, j++) {
  466.        k = i + 1;
  467.        first = lzhuf->freq[j] = lzhuf->freq[i] + lzhuf->freq[k];
  468.        for (k = j - 1; first < lzhuf->freq[k]; k--);
  469.        k++;
  470.     {    register unsigned *p, *e;
  471.         for (p = &lzhuf->freq[j], e = &lzhuf->freq[k]; p > e; p--)
  472.             p[0] = p[-1];
  473.         lzhuf->freq[k] = first;
  474.     }
  475.     {    register int *p, *e;
  476.         for (p = &lzhuf->son[j], e = &lzhuf->son[k]; p > e; p--)
  477.             p[0] = p[-1];
  478.         lzhuf->son[k] = i;
  479.     }
  480.    }
  481.    /* connect prnt */
  482.    for(i = 0; i < T; i++) {
  483.        if((k = lzhuf->son[i]) >= T) {
  484.           lzhuf->prnt[k] = i;
  485.        } else {
  486.           lzhuf->prnt[k] = lzhuf->prnt[k + 1] = i;
  487.        }
  488.    }
  489. }
  490.  
  491.  
  492. /* increment frequency of given code by one, and update tree */
  493. void update(struct lzhufstruct *lzhuf, int c)
  494. {
  495.    int i, j, k, l;
  496.  
  497.    if(lzhuf->freq[R] == MAX_FREQ) {
  498.       reconst(lzhuf);
  499.    }
  500.    c = lzhuf->prnt[c + T];
  501.    do {
  502.       k = ++lzhuf->freq[c];
  503.  
  504.       /* if the order is disturbed, exchange nodes */
  505.       if((unsigned)k > lzhuf->freq[l = c + 1]) {
  506.          while ((unsigned) k > lzhuf->freq[++l]);
  507.          l--;
  508.          lzhuf->freq[c] = lzhuf->freq[l];
  509.          lzhuf->freq[l] = k;
  510.  
  511.          i = lzhuf->son[c];
  512.          lzhuf->prnt[i] = l;
  513.          if (i < T) lzhuf->prnt[i + 1] = l;
  514.  
  515.          j = lzhuf->son[l];
  516.          lzhuf->son[l] = i;
  517.  
  518.          lzhuf->prnt[j] = c;
  519.          if (j < T) lzhuf->prnt[j + 1] = c;
  520.          lzhuf->son[c] = j;
  521.  
  522.          c = l;
  523.       }
  524.    } while ((c = lzhuf->prnt[c]) != 0);   /* repeat up to root */
  525. }
  526.  
  527. void EncodeChar(struct lzhufstruct *lzhuf, unsigned c)
  528. {
  529.    unsigned i;
  530.    int j, k;
  531.  
  532.    i = 0;
  533.    j = 0;
  534.    k = lzhuf->prnt[c + T];
  535.  
  536.    /* travel from leaf to root */
  537.    do {
  538.       i >>= 1;
  539.  
  540.       /* if node's address is odd-numbered, choose bigger brother node */
  541.       if (k & 1) i += 0x8000;
  542.  
  543.       j++;
  544.    } while ((k = lzhuf->prnt[k]) != R);
  545.    Putcode(lzhuf, j, i);
  546.    lzhuf->code = i;
  547.    lzhuf->len = j;
  548.    update(lzhuf, c);
  549. }
  550.  
  551. void EncodePosition(struct lzhufstruct *lzhuf, unsigned c)
  552. {
  553.    unsigned i;
  554.  
  555.    /* output upper 6 bits by table lookup */
  556.    i = c >> 6;
  557. #ifdef DEBUG
  558.    if (i >= MAX_P_LEN)
  559.       tcmdprintf("Ah....FYI...you've just exceded the MAX_P_LEN variable ( %d ) with %d\n", MAX_P_LEN, i);
  560. #endif
  561.    Putcode(lzhuf, p_len[i], (unsigned)p_code[i] << 8);
  562.  
  563.    /* output lower 6 bits verbatim */
  564.    Putcode(lzhuf, 6, (c & 0x3f) << 10);
  565. }
  566.  
  567. void EncodeEnd(struct lzhufstruct *lzhuf)
  568. {
  569.    if(lzhuf->putlen) {
  570.       if(putc(lzhuf->putbuf >> 8, lzhuf->oFile) == EOF) {
  571.          return;
  572.       }
  573.       lzhuf->codesize++;
  574.    }
  575. }
  576.  
  577. int DecodeChar(struct lzhufstruct *lzhuf)
  578. {
  579.    unsigned c;
  580.  
  581.    c = lzhuf->son[R];
  582.  
  583.    /* travel from root to leaf, */
  584.    /* choosing the smaller child node (son[]) if the read bit is 0, */
  585.    /* the bigger (son[]+1} if 1 */
  586.    while (c < T) {
  587.        c += GetBit(lzhuf);
  588.        c = lzhuf->son[c];
  589.    }
  590.    c -= T;
  591.    update(lzhuf, c);
  592.    return c;
  593. }
  594.  
  595. int DecodePosition(struct lzhufstruct *lzhuf)
  596. {
  597.    unsigned j, c;
  598.    unsigned short i;
  599.  
  600.    /* recover upper 6 bits from table */
  601.    i = GetByte(lzhuf);
  602. #ifdef DEBUG
  603.    if (i >= MAX_D_LEN)
  604.       tcmdprintf("Ah....FYI...you've just exceded the MAX_D_LEN variable ( %u ) with %u\n", MAX_D_LEN, i);
  605. #endif
  606.    c = (unsigned)d_code[i] << 6;
  607.    j = d_len[i];
  608.  
  609.    /* read lower 6 bits verbatim */
  610.    j -= 2;
  611.    while (j--) {
  612.       i = (i << 1) + GetBit(lzhuf);
  613.    }
  614.    return c | (i & 0x3f);
  615. }
  616.  
  617. /* compression */
  618. int Encode(int usock OPTIONAL, char *txtFileName, char *binFileName, struct lzhufstruct *lzhuf, int trace)
  619. {
  620.    int  i, c, len, r, s, last_match_length;
  621.  
  622.    unsigned long int  filesize   = 0;
  623.  
  624.    #ifdef DEBUG
  625.       tcmdprintf("Encoding %s into %s\n", txtFileName, binFileName);
  626.    #endif
  627.  
  628.    /* Open input and output files. */
  629.    if((lzhuf->iFile = fopen(txtFileName, "rb")) == NULLFILE) {
  630.       if (trace)
  631.            tcmdprintf(Erroropening, txtFileName, Encodestr);
  632.       return 0;
  633.    }
  634.  
  635.    if((lzhuf->oFile = fopen(binFileName, "wb")) == NULLFILE) {
  636.       if (trace)
  637.            tcmdprintf(Erroropening, binFileName, Encodestr);
  638.       return 0;
  639.    }
  640.  
  641.    fseek(lzhuf->iFile, 0L, 2);
  642.    filesize = ftell(lzhuf->iFile);
  643.    if(filesize == 0)
  644.       return 0;
  645.    /* output size of text */
  646.    if(fwrite(&filesize, sizeof(filesize), 1, lzhuf->oFile) < 1)
  647.       return 0;
  648.    rewind(lzhuf->iFile);
  649.  
  650.    lzhuf->iFileSize = filesize;
  651.    filesize = 0;                   /* rewind and re-read */
  652.  
  653.    StartHuff(lzhuf);
  654.    InitTree(lzhuf);
  655.  
  656.    s = 0;
  657.    r = N - F;
  658.    for(i = s; i < r; i++)
  659.        lzhuf->text_buf[i] = ' ';
  660.    for(len = 0; len < F && (c = getc(lzhuf->iFile)) != EOF; len++)
  661.        lzhuf->text_buf[r + len] = c;
  662.    filesize = len;
  663.    for(i = 1; i <= F; i++)
  664.        InsertNode(lzhuf, r - i);
  665.    InsertNode(lzhuf, r);
  666.    do {
  667.       pwait(NULL);
  668.       if(lzhuf->match_length > len)
  669.          lzhuf->match_length = len;
  670.       if(lzhuf->match_length <= THRESHOLD) {
  671.          lzhuf->match_length = 1;
  672.          EncodeChar(lzhuf,lzhuf->text_buf[r]);
  673.       } else {
  674.          EncodeChar(lzhuf,255 - THRESHOLD + lzhuf->match_length);
  675.          EncodePosition(lzhuf,lzhuf->match_position);
  676.       }
  677.       last_match_length = lzhuf->match_length;
  678.       for(i = 0; i < last_match_length && (c = getc(lzhuf->iFile)) != EOF; i++) {
  679.          DeleteNode(lzhuf, s);
  680.          lzhuf->text_buf[s] = c;
  681.          if(s < F - 1)
  682.             lzhuf->text_buf[s + N] = c;
  683.          s = (s + 1) & (N - 1);
  684.          r = (r + 1) & (N - 1);
  685.          InsertNode(lzhuf, r);
  686.       }
  687.       while(i++ < last_match_length) {
  688.          DeleteNode(lzhuf, s);
  689.          s = (s + 1) & (N - 1);
  690.          r = (r + 1) & (N - 1);
  691.          if (--len) InsertNode(lzhuf, r);
  692.       }
  693.    } while (len > 0);
  694.    EncodeEnd(lzhuf);
  695.    fclose(lzhuf->iFile);
  696.    fclose(lzhuf->oFile);
  697.  
  698.    if(lzhuf->iFileSize == 0)
  699.       lzhuf->iFileSize  = 1;
  700.    if (trace)
  701.          tcmdprintf(ENCODEratio, lzhuf->iFileSize, lzhuf->codesize,
  702.                 (100 - ((lzhuf->codesize*100) / lzhuf->iFileSize)));
  703.    return 1;
  704. }
  705.  
  706. int Decode(int usock OPTIONAL, char *iFile, char *oFile, struct lzhufstruct *lzhuf, int addex, int trace)
  707. {
  708.    int  i = 0;
  709.    int  j = 0;
  710.    int  k = 0;
  711.    int  r = 0;
  712.    int  c = 0;
  713.  
  714.    unsigned long int  count      = 0;
  715.             long int  filesize   = 0;
  716.  
  717.    #ifdef DEBUG
  718.       tcmdprintf("Decoding %s into %s\n", iFile, oFile);
  719.    #endif
  720.  
  721.    /* Open input and output files. */
  722.    if((lzhuf->iFile = fopen(iFile, "rb")) == NULLFILE)    {
  723.       if (trace)
  724.            tcmdprintf(Erroropening, iFile, Decodestr);
  725.       return 0;
  726.    }
  727.  
  728.    if ((lzhuf->oFile = fopen(oFile, "wb")) == NULLFILE)    {
  729.       if (trace)
  730.            tcmdprintf (Erroropening, oFile, Decodestr);
  731.       return 0;
  732.    }
  733.  
  734.    fseek(lzhuf->iFile, 0L, 2);
  735.    filesize = ftell(lzhuf->iFile);
  736.    if(filesize == 0)
  737.       return 0;
  738.    lzhuf->iFileSize = filesize;
  739.    rewind(lzhuf->iFile);
  740.  
  741.    if(fread(&filesize, sizeof(filesize), 1, lzhuf->iFile) < 1)
  742.       return 0;
  743.    if(filesize == 0)
  744.       return 0;
  745.  
  746.    StartHuff(lzhuf);
  747.    for(i = 0; i < N - F; i++)
  748.       lzhuf->text_buf[i] = ' ';
  749.  
  750.    r = N - F;
  751.    for(count = 0; count < (unsigned long)filesize; ) {
  752.       pwait(NULL);
  753.       c = DecodeChar(lzhuf);
  754.       if(c < 256) {
  755.          if(putc(c, lzhuf->oFile) == EOF) {
  756.             return 0;
  757.          }
  758.          lzhuf->text_buf[r++] = c;
  759.          r &= (N - 1);
  760.          count++;
  761.       } else {
  762.          i = (r - DecodePosition(lzhuf) - 1) & (N - 1);
  763.          j = c - 255 + THRESHOLD;
  764.          for(k = 0; k < j; k++) {
  765.             c = lzhuf->text_buf[(i + k) & (N - 1)];
  766.             if(putc(c, lzhuf->oFile) == EOF) {
  767.                return 0;
  768.             }
  769.             lzhuf->text_buf[r++] = c;
  770.             r &= (N - 1);
  771.             count++;
  772.          }
  773.       }
  774.    }
  775.  
  776.    #ifndef STANDALONE
  777.    if (addex)
  778.        /* This terminates a note. */
  779.        fputs("\n/EX\n",lzhuf->oFile);
  780.    #endif
  781.  
  782.    fclose(lzhuf->iFile);
  783.    fclose(lzhuf->oFile);
  784.  
  785.    if(count == 0)
  786.       count  = 1;
  787.    if (trace)
  788.          tcmdprintf (DECODEratio, lzhuf->iFileSize, count,
  789.                 (100 - ((lzhuf->iFileSize*100) / count)));
  790.    return 1;
  791. }
  792.  
  793. #ifndef STANDALONE
  794. int send_yapp(struct fwd *f, char *txtFileName, char *subj) {
  795.    #define SLEN 79                           /* Maximum subject     */
  796.                                              /* filename length.    */
  797.  
  798.    int  oldmode;                             /* Socket Mode holder. */
  799.    #ifdef DEBUG2
  800.       FILE *debug;
  801.    #endif
  802.  
  803.    char *buffer;                             /* buffer data.        */
  804.    int  buffer_len;                          /* buffer Length.      */
  805.  
  806.    int  x;                                   /* misc counter.       */
  807.    int  cnt;                                 /* misc counter.       */
  808.    int  rc;
  809.    int  Error;
  810.    int  usock;
  811.  
  812.    short b_checksum;                         /* buffer checksum.    */
  813.    short f_checksum;                         /* file checksum.      */
  814.  
  815.    FILE *binFile;
  816.  
  817.    char  binFileName[80];
  818.  
  819.    /* Debug info. */
  820.       #ifdef DEBUG2
  821.          if (((debug  = fopen(tmpnam(NULL),"wb")) == NULLFILE)) {
  822.             printf("Error opening input file.\n");
  823.             return 0;
  824.          }
  825.       #endif
  826.  
  827.    /* User socket */
  828.       usock = f->m->user;
  829.  
  830.    /* Encode code. */
  831.       tmpnam(binFileName);
  832.  
  833.       Error = FALSE;
  834.  
  835.       pwait(NULL);
  836.       AllocDataBuffers(f);
  837.       rc = Encode(usock, txtFileName, binFileName, f->lzhuf, FBBtrace);
  838.       FreeDataBuffers(f);
  839.       pwait(NULL);
  840.       if(!rc) {
  841.      if (FBBtrace)
  842.          tcmdprintf (ErrorEncode, rc);
  843.          log(f->m->user, ErrorEncode, rc);
  844.          Error = TRUE;
  845.      unlink(binFileName);    /* just in case */
  846.       }
  847.       unlink(txtFileName);
  848.  
  849.  
  850.    if(Error)
  851.       return 0;
  852.  
  853.    /* open the compressed data file. */
  854.       /* Now... we're going to read from the file and close it when we exit. */
  855.  
  856.       /* Open the input file. */
  857.       binFile = fopen(binFileName, "rb");
  858.  
  859.    /* Debug info. */
  860.       #ifdef DEBUG
  861.          tcmdprintf("we opened %s for input.\n",  f->oFile);
  862.       #endif
  863.  
  864.       /* Grab some space. Largest YAPP packet is 250+ bytes. */
  865.       f->tmpBuffer       = mallocw(260);
  866.       buffer    = f->tmpBuffer;
  867.  
  868.       /* Set the socket to Binary mode since we'll be sending Binary data. */
  869.       oldmode = sockmode(usock,SOCK_BINARY);
  870.  
  871.    /* Send the subject buffer
  872.          The buffer is setup as follows:
  873.          Pos Data
  874.            1 SOH
  875.            2 Length of entire buffer ( 8 bytes + strlen(subject) )
  876.            3 Null terminated Subject string.
  877.            x Null terminated '0' string.
  878.     */
  879.  
  880.       /* Make sure that the subject strlen() is equal to or less than SLEN */
  881.       x = strlen(subj);
  882.       if (x >= SLEN) {
  883.          x = SLEN;
  884.          subj[SLEN] = '\0';
  885.       }
  886.  
  887.       /* length of subject + NULL + length of "     0" + NULL */
  888.       buffer_len = x + 1 + 6 + 1;
  889.  
  890.       /* Build the buffer. */
  891.       buffer[0] = SOH;                       /* buffer_Type                */
  892.       buffer[1] = buffer_len;                /* buffer_Len                 */
  893.       strcpy(&buffer[2], subj);              /* Subject info.              */
  894.       strcpy(&buffer[x+3], "     0");        /* Always 0 for FBB Messages. */
  895.  
  896.       /* Now we can send it.                       */
  897.       /* buffer_len + 2 ( for the first two bytes. */
  898.       usputbuf(usock, buffer, buffer_len+2);
  899.       #ifdef DEBUG2
  900.           fwrite(buffer, buffer_len+2, 1, debug);
  901.       #endif
  902.  
  903.    /* Send the data buffers. */
  904.       f_checksum = 0;
  905.       /* fill buffer with data. Bytes 0 and 1 are reserved. */
  906.       while ((x = fread(&buffer[2], 1, 250, binFile)) > 0) {
  907.          /* prepare the buffer. */
  908.          buffer[0]  = STX;                         /* buffer_Type       */
  909.          buffer[1]  = x;                           /* buffer_Len        */
  910.  
  911.          b_checksum = 0;
  912.          for (cnt=0;cnt<x;cnt++) {
  913.              b_checksum += buffer[2 + cnt];        /* buffer checksum.  */
  914.          }
  915. #if 0    /* must be for FBB 4.15C ?? */
  916.          buffer[x + 2] = ((-b_checksum) & 0xff);   /* Store b_checksum. */
  917. #endif
  918.  
  919.          /* and send it. */
  920.          usputbuf(usock, buffer, (x + 2));
  921.          #ifdef DEBUG2
  922.             fwrite(buffer, x + 2, 1, debug);
  923.          #endif
  924.  
  925.          f_checksum += b_checksum;
  926.       } /* endwhile */
  927.  
  928.    /* Send the EOT */
  929.       /* Prepare the buffer. */
  930.       buffer[0] = EOT;                             /* buffer_Type */
  931.       buffer[1] = ((-f_checksum) & 0xff);          /* Checksum.   */
  932.  
  933.       /* and send it. */
  934.       usputbuf(usock, buffer, 2);
  935.       #ifdef DEBUG2
  936.          fwrite(buffer, 2, 1, debug);
  937.       #endif
  938.  
  939.    /* Terminate. */
  940.       fclose(binFile);
  941.  
  942.    /* Delete binFileName */
  943.       unlink (binFileName);
  944.  
  945.       #ifdef DEBUG2
  946.          fclose(debug);
  947.       #endif
  948.       free (f->tmpBuffer);
  949.       /* Set the socket back to it's orginal mode. */
  950.       sockmode(usock,oldmode);
  951.    return 1;
  952. }
  953.  
  954.  
  955. int recv_yapp(struct fwd *f) {
  956.    int  recvcnt;
  957.    int  packet_type;
  958.    unsigned int  packet_size;
  959.    char packet_data[258];
  960.    int  GetSubject;
  961.    int  NoteDone;
  962.    int  NoteError;
  963.    unsigned int  rx_checksumctr;
  964.    unsigned int  rx_checksum;
  965.    int  rc;
  966.    int  oldmode;                             /* Socket Mode holder. */
  967.    FILE *iFile = NULLFILE;
  968.    int  usock;
  969.  
  970.    /* User socket */
  971.       usock = f->m->user;
  972.  
  973.    /* Set the socket to Binary mode since we'll be sending Binary data. */
  974.       oldmode = sockmode(usock,SOCK_BINARY);
  975.  
  976.       GetSubject    = TRUE;
  977.       NoteDone      = FALSE;
  978.       NoteError     = FALSE;
  979.       rx_checksum   = 0;
  980.  
  981.       while(!NoteDone) {
  982.          /* Get the data packets. */
  983.          packet_type = recvchar(usock);
  984.  
  985.          if (GetSubject) {
  986.              if (packet_type != SOH) {
  987.                  FBBerror (0, usock, f->m);
  988.          NoteDone = NoteError = TRUE;
  989.                  continue;
  990.              }
  991.          } else
  992.          if ((packet_type != STX) && (packet_type != EOT))  {
  993.              /* Get the packet size. */
  994.              packet_size = recvchar(usock);
  995.              FBBerror (3, usock, f->m);
  996.          NoteDone = NoteError = TRUE;
  997.              continue;
  998.          }
  999.  
  1000.          /* Get the packet size. */
  1001.          packet_size = recvchar(usock);
  1002.      if (!packet_size)
  1003.         packet_size=256;   /* 0x00 always means 256 */
  1004.  
  1005.          if (packet_type == SOH) {
  1006.             /* This is the subject. Reset the flag so we don't */
  1007.             /* come here again.                                */
  1008.             GetSubject = FALSE;
  1009.  
  1010.             /* Open the output file. */
  1011.            if (iFile == NULLFILE)    /* shouldn't be needed, but just in case */
  1012.                     iFile = fopen(f->iFile, "wb");
  1013.  
  1014.             /* This is a subject packet (with the offset hiding behind it). */
  1015.             recvcnt = recvbuf(usock, &packet_data[0], packet_size+1);
  1016.         /* we have now read the subject (which we'll use) and the
  1017.            offset (which we are assuming to be zero), which we ignore */
  1018.             if(recvcnt == -1) {
  1019.            if (FBBtrace)    {
  1020.            tcmdprintf (lostremote);
  1021.            tcmdprintf ("\n");
  1022.            }
  1023.                log(f->m->user, lostremote);
  1024.                /* We've lost the connection.... */
  1025.                NoteDone = NoteError = TRUE;
  1026.             } else
  1027.                f->m->subject = strdup(packet_data);
  1028.          } /* endif */
  1029.          else
  1030.          if (packet_type == STX) {
  1031.             /* Validate the packet       */
  1032.             /* and write it to the file. */
  1033.             recvcnt = recvbuf(usock, &packet_data[0], packet_size+1);
  1034.             if(recvcnt == -1) {
  1035.            if (FBBtrace)    {
  1036.            tcmdprintf (lostremote);
  1037.            tcmdprintf ("\n");
  1038.            }
  1039.                log(f->m->user, lostremote);
  1040.                /* We've lost the connection.... */
  1041.                NoteDone = NoteError = TRUE;
  1042.             } else {
  1043.                /* Write to disk */
  1044.                fwrite(packet_data, recvcnt, 1, iFile);
  1045.  
  1046.                /* add the data to the rx_checksum count. */
  1047.                for(rx_checksumctr=0;rx_checksumctr<packet_size;rx_checksumctr++) {
  1048.                   rx_checksum += (unsigned char) packet_data[rx_checksumctr];
  1049.                }
  1050.             }
  1051.          } /* endif */
  1052.          else
  1053.          if (packet_type == EOT) {
  1054.             /* Close the file.                  */
  1055.             /* Validate the Checksum.           */
  1056.             /* erase the file if Checksum fails.*/
  1057.             /* Get ready to read next message.  */
  1058.  
  1059.         if (packet_size == 256)
  1060.             packet_size = 0;
  1061.         if (packet_size != ((-rx_checksum) & 0xff))    {
  1062.             NoteDone = NoteError = TRUE;
  1063.             usputs (usock, "*** CHECKSUM ERROR\n");
  1064.             if (FBBtrace)
  1065.                 tcmdprintf ("FBBCMP: Checksum Error in message data\n");
  1066.             log (f->m->user, "Checksum Error in message data");
  1067.         } else if (FBBtrace)
  1068.             tcmdprintf ("FBBCMP: YAPP Message Checksum verified\n");
  1069.             /* Close the data file. */
  1070.             fclose(iFile);
  1071.             iFile = NULLFILE;
  1072.  
  1073.             /* We're done with this message. Return. */
  1074.             NoteDone  = TRUE;
  1075.          } /* endif */
  1076.       } /* End while !NoteDone */
  1077.  
  1078.       if(!NoteError) {
  1079.          pwait(NULL);
  1080.          AllocDataBuffers(f);
  1081.          rc = Decode(usock, f->iFile, f->oFile, f->lzhuf, 1, FBBtrace);
  1082.          FreeDataBuffers(f);
  1083.          pwait(NULL);
  1084.          if(!rc)    {
  1085.             if (FBBtrace)
  1086.             tcmdprintf (ErrorDecode, rc);
  1087.             log(f->m->user, ErrorDecode, rc);
  1088.             NoteError = TRUE;
  1089.          }
  1090.       }
  1091.       if (iFile != NULLFILE)
  1092.          fclose(iFile);
  1093.  
  1094.       /* delete compressed file. */
  1095.       unlink(f->iFile);
  1096.  
  1097.       /* Set the socket back to it's orginal mode. */
  1098.       sockmode(usock,oldmode);
  1099.       if(!NoteError)
  1100.          return 1;
  1101.       else
  1102.          return 0;
  1103. }
  1104.  
  1105. /* Receive a buffer from a socket, returning # chars read.
  1106.  */
  1107. int recvbuf(int s, char *buf, unsigned len) {
  1108.     int c;
  1109.     int cnt = 0;
  1110.  
  1111.     while(len-- > 1){
  1112.         if((c = recvchar(s)) == EOF){
  1113.             cnt = -1;
  1114.             break;
  1115.         }
  1116.         if(buf != NULLCHAR)
  1117.             *buf++ = c;
  1118.         cnt++;
  1119.     }
  1120.     return cnt;
  1121. }
  1122. #endif
  1123.  
  1124.  
  1125. #ifdef XFWD
  1126. int send_lzhuf (struct fwd *f, char *txtFileName)
  1127. {
  1128. int oldmode;                             /* Socket Mode holder. */
  1129. int rc, c;
  1130. int Error;
  1131. int usock;
  1132. FILE *binFile;
  1133. char  binFileName[80];
  1134. int16 newchecksum = 0;
  1135.  
  1136.     /* User socket */
  1137.     usock = f->m->user;
  1138.  
  1139.     /* Encode code. */
  1140.     tmpnam (binFileName);
  1141.  
  1142.     Error = FALSE;
  1143.  
  1144.     pwait (NULL);
  1145.     AllocDataBuffers (f);
  1146.     rc = Encode (usock, txtFileName, binFileName, f->lzhuf, Xtrace);
  1147.     FreeDataBuffers (f);
  1148.     pwait(NULL);
  1149.     if (!rc) {
  1150.         if (Xtrace)
  1151.             tcmdprintf (ErrorEncode, rc);
  1152.         log (f->m->user, ErrorEncode, rc);
  1153.         Error = TRUE;
  1154.         unlink (binFileName);    /* just in case */
  1155.     }
  1156.     unlink (txtFileName);
  1157.  
  1158.     if (Error)    {
  1159.         tprintf ("SS 0\n");
  1160.         return 0;
  1161.     }
  1162.  
  1163.     /* open the compressed data file. */
  1164.     /* Now... we're going to read from the file and close it when we exit. */
  1165.  
  1166.     pwait (NULL);
  1167.  
  1168.     /* Open the input file. */
  1169.     binFile = fopen (binFileName, "rb");
  1170.  
  1171.     pwait (NULL);
  1172.  
  1173.     /* Calculate checksum */
  1174.     while ((c = fgetc (binFile)) != EOF)
  1175.         newchecksum += c;
  1176.  
  1177.     rewind (binFile);
  1178.     pwait (NULL);
  1179.     
  1180.     tprintf ("SS %ld %u\n", filelength (fileno(binFile)), newchecksum);
  1181.     if (Xtrace)
  1182.         tcmdprintf ("XFWD: Sending 'SS %ld %u'\n", filelength (fileno(binFile)), newchecksum);
  1183.  
  1184.     /* Set the socket to Binary mode since we'll be sending Binary data. */
  1185.     oldmode = sockmode (usock, SOCK_BINARY);
  1186.  
  1187.     while ((c = fgetc (binFile)) != EOF)
  1188.         tputc (c);
  1189.  
  1190.     /* Terminate. */
  1191.     fclose (binFile);
  1192.  
  1193.     /* Delete binFileName */
  1194.     unlink (binFileName);
  1195.  
  1196.     /* Set the socket back to it's orginal mode. */
  1197.     sockmode (usock, oldmode);
  1198.     return 1;
  1199. }
  1200.  
  1201.  
  1202. int recv_lzhuf (struct fwd *f, int msgsize, int16 *newchecksum)
  1203. {
  1204. int c;
  1205. int Error = FALSE;
  1206. int rc;
  1207. int oldmode;                             /* Socket Mode holder. */
  1208. FILE *iFile = NULLFILE;
  1209. int  usock;
  1210.  
  1211.     *newchecksum = 0;
  1212.  
  1213.     /* User socket */
  1214.     usock = f->m->user;
  1215.  
  1216.     /* Set the socket to Binary mode since we'll be sending Binary data. */
  1217.     oldmode = sockmode (usock, SOCK_BINARY);
  1218.  
  1219.     iFile = fopen(f->iFile, "wb");
  1220.     
  1221.     while(msgsize--) {
  1222.         /* Get the data. */
  1223.         c = recvchar (usock);
  1224.         *newchecksum += c;
  1225.         fputc (c, iFile);
  1226.     }
  1227.  
  1228.     fclose (iFile);
  1229.     AllocDataBuffers (f);
  1230.     rc = Decode (usock, f->iFile, f->oFile, f->lzhuf, 0, Xtrace);
  1231.     FreeDataBuffers (f);
  1232.     if (!rc)    {
  1233.         if (Xtrace)
  1234.             tcmdprintf (ErrorDecode, rc);
  1235.         log (f->m->user, ErrorDecode, rc);
  1236.         Error = TRUE;
  1237.     }
  1238.  
  1239.     /* delete compressed file. */
  1240.     unlink (f->iFile);
  1241.  
  1242.     pwait (NULL);
  1243.  
  1244.     /* Set the socket back to it's orginal mode. */
  1245.     sockmode (usock, oldmode);
  1246.     if (!Error)
  1247.         return 1;
  1248.     else
  1249.         return 0;
  1250. }
  1251.  
  1252. #endif
  1253.  
  1254.  
  1255. #ifdef STANDALONE
  1256. int pwait (volatile void *event)
  1257. {
  1258. }
  1259.  
  1260. main(argc, argv, envp)
  1261. int argc;
  1262. char *argv[];
  1263. char *envp[];
  1264. {
  1265. struct fwd f;
  1266.  
  1267.     AllocDataBuffers (&f);
  1268.     if (argv[1][0] == 'd') {
  1269.         Decode(0, argv[2], argv[3], f.lzhuf, 0, FBBtrace);
  1270.     } else {
  1271.         Encode(0, argv[2], argv[3], f.lzhuf, FBBtrace);
  1272.     } /* endif */
  1273. }
  1274. #endif
  1275. #endif
  1276.